home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / perl5 / HTTP / Headers / Util.pm < prev   
Encoding:
Perl POD Document  |  2008-10-20  |  4.8 KB  |  200 lines

  1. package HTTP::Headers::Util;
  2.  
  3. use strict;
  4. use vars qw($VERSION @ISA @EXPORT_OK);
  5.  
  6. $VERSION = "5.817";
  7.  
  8. require Exporter;
  9. @ISA=qw(Exporter);
  10.  
  11. @EXPORT_OK=qw(split_header_words _split_header_words join_header_words);
  12.  
  13.  
  14.  
  15. sub split_header_words {
  16.     my @res = &_split_header_words;
  17.     for my $arr (@res) {
  18.     for (my $i = @$arr - 2; $i >= 0; $i -= 2) {
  19.         $arr->[$i] = lc($arr->[$i]);
  20.     }
  21.     }
  22.     return @res;
  23. }
  24.  
  25. sub _split_header_words
  26. {
  27.     my(@val) = @_;
  28.     my @res;
  29.     for (@val) {
  30.     my @cur;
  31.     while (length) {
  32.         if (s/^\s*(=*[^\s=;,]+)//) {  # 'token' or parameter 'attribute'
  33.         push(@cur, $1);
  34.         # a quoted value
  35.         if (s/^\s*=\s*\"([^\"\\]*(?:\\.[^\"\\]*)*)\"//) {
  36.             my $val = $1;
  37.             $val =~ s/\\(.)/$1/g;
  38.             push(@cur, $val);
  39.         # some unquoted value
  40.         }
  41.         elsif (s/^\s*=\s*([^;,\s]*)//) {
  42.             my $val = $1;
  43.             $val =~ s/\s+$//;
  44.             push(@cur, $val);
  45.         # no value, a lone token
  46.         }
  47.         else {
  48.             push(@cur, undef);
  49.         }
  50.         }
  51.         elsif (s/^\s*,//) {
  52.         push(@res, [@cur]) if @cur;
  53.         @cur = ();
  54.         }
  55.         elsif (s/^\s*;// || s/^\s+//) {
  56.         # continue
  57.         }
  58.         else {
  59.         die "This should not happen: '$_'";
  60.         }
  61.     }
  62.     push(@res, \@cur) if @cur;
  63.     }
  64.     @res;
  65. }
  66.  
  67.  
  68. sub join_header_words
  69. {
  70.     @_ = ([@_]) if @_ && !ref($_[0]);
  71.     my @res;
  72.     for (@_) {
  73.     my @cur = @$_;
  74.     my @attr;
  75.     while (@cur) {
  76.         my $k = shift @cur;
  77.         my $v = shift @cur;
  78.         if (defined $v) {
  79.         if ($v =~ /[\x00-\x20()<>@,;:\\\"\/\[\]?={}\x7F-\xFF]/ || !length($v)) {
  80.             $v =~ s/([\"\\])/\\$1/g;  # escape " and \
  81.             $k .= qq(="$v");
  82.         }
  83.         else {
  84.             # token
  85.             $k .= "=$v";
  86.         }
  87.         }
  88.         push(@attr, $k);
  89.     }
  90.     push(@res, join("; ", @attr)) if @attr;
  91.     }
  92.     join(", ", @res);
  93. }
  94.  
  95.  
  96. 1;
  97.  
  98. __END__
  99.  
  100. =head1 NAME
  101.  
  102. HTTP::Headers::Util - Header value parsing utility functions
  103.  
  104. =head1 SYNOPSIS
  105.  
  106.   use HTTP::Headers::Util qw(split_header_words);
  107.   @values = split_header_words($h->header("Content-Type"));
  108.  
  109. =head1 DESCRIPTION
  110.  
  111. This module provides a few functions that helps parsing and
  112. construction of valid HTTP header values.  None of the functions are
  113. exported by default.
  114.  
  115. The following functions are available:
  116.  
  117. =over 4
  118.  
  119.  
  120. =item split_header_words( @header_values )
  121.  
  122. This function will parse the header values given as argument into a
  123. list of anonymous arrays containing key/value pairs.  The function
  124. knows how to deal with ",", ";" and "=" as well as quoted values after
  125. "=".  A list of space separated tokens are parsed as if they were
  126. separated by ";".
  127.  
  128. If the @header_values passed as argument contains multiple values,
  129. then they are treated as if they were a single value separated by
  130. comma ",".
  131.  
  132. This means that this function is useful for parsing header fields that
  133. follow this syntax (BNF as from the HTTP/1.1 specification, but we relax
  134. the requirement for tokens).
  135.  
  136.   headers           = #header
  137.   header            = (token | parameter) *( [";"] (token | parameter))
  138.  
  139.   token             = 1*<any CHAR except CTLs or separators>
  140.   separators        = "(" | ")" | "<" | ">" | "@"
  141.                     | "," | ";" | ":" | "\" | <">
  142.                     | "/" | "[" | "]" | "?" | "="
  143.                     | "{" | "}" | SP | HT
  144.  
  145.   quoted-string     = ( <"> *(qdtext | quoted-pair ) <"> )
  146.   qdtext            = <any TEXT except <">>
  147.   quoted-pair       = "\" CHAR
  148.  
  149.   parameter         = attribute "=" value
  150.   attribute         = token
  151.   value             = token | quoted-string
  152.  
  153. Each I<header> is represented by an anonymous array of key/value
  154. pairs.  The keys will be all be forced to lower case.
  155. The value for a simple token (not part of a parameter) is C<undef>.
  156. Syntactically incorrect headers will not necessary be parsed as you
  157. would want.
  158.  
  159. This is easier to describe with some examples:
  160.  
  161.    split_header_words('foo="bar"; port="80,81"; DISCARD, BAR=baz');
  162.    split_header_words('text/html; charset="iso-8859-1"');
  163.    split_header_words('Basic realm="\\"foo\\\\bar\\""');
  164.  
  165. will return
  166.  
  167.    [foo=>'bar', port=>'80,81', discard=> undef], [bar=>'baz' ]
  168.    ['text/html' => undef, charset => 'iso-8859-1']
  169.    [basic => undef, realm => "\"foo\\bar\""]
  170.  
  171. If you don't want the function to convert tokens and attribute keys to
  172. lower case you can call it as C<_split_header_words> instead (with a
  173. leading underscore).
  174.  
  175. =item join_header_words( @arrays )
  176.  
  177. This will do the opposite of the conversion done by split_header_words().
  178. It takes a list of anonymous arrays as arguments (or a list of
  179. key/value pairs) and produces a single header value.  Attribute values
  180. are quoted if needed.
  181.  
  182. Example:
  183.  
  184.    join_header_words(["text/plain" => undef, charset => "iso-8859/1"]);
  185.    join_header_words("text/plain" => undef, charset => "iso-8859/1");
  186.  
  187. will both return the string:
  188.  
  189.    text/plain; charset="iso-8859/1"
  190.  
  191. =back
  192.  
  193. =head1 COPYRIGHT
  194.  
  195. Copyright 1997-1998, Gisle Aas
  196.  
  197. This library is free software; you can redistribute it and/or
  198. modify it under the same terms as Perl itself.
  199.  
  200.